【AWS】簡単!berkshelfとchefを使ってPostfixからSESでメールを送ってみた
はじめに
こんにちは植木和樹です。先日Developers.IO AWS関連ブログ500本目記念として、弊社 望月が英語ブログを投稿しました。
How to send Email from PHP application via Amazon SES | Developers.IO
ブログではEC2からSESをリレーしてメール送信するためのPostfix設定方法を紹介しています。/etc/postfixにいくつかファイルを用意するだけで、意外と簡単にSESが利用できるようですね。
既存システムをAWSへ移行するにあたって、アプリケーションの改修を行わず、サーバーからメールを手軽に送りたいという需要は多いのではないでしょうか。ということで、誰でも簡単にSESが利用できるようChefでPostfixを設定してみました。
事前準備
次のものを事前に準備しておきます。今回はSESをSandbox環境で使用するため、利用するメールアドレスを事前に認証しておきます。本番運用環境で使用する際には、別途AWSへのプロダクション申請とドメイン認証が必要になります。
- メールを送るEC2サーバー(これにPostfixを設定する)
- SES SMTP credentials(SESと通信する権限を持ったIAMユーザーのアクセスキーとシークレットキー)
- 認証された 送信元メールアドレス
- 認証された 送信先メールアドレス
- knife-solo + berkshelfがインストールされたローカルマシン
メールを送るEC2サーバー
適当なEC2サーバーを用意してください。Postfixはchef-soloで設定するのでssh(tcp/22)の通信をセキュリティグループで許可しておきます。
SES SMTP credentials
マネージメントコンソールのSESの画面から「Create My SMTP Credentials」をクリックして、クレデンシャルを作成します。
IAM User名を入力して「Create」します。
SESを利用するためのIAMユーザーが作成されました。クレデンシャルファイルをダウンロードし、ファイルに記載されているアクセスキーとシークレットアクセスキーを控えておきましょう。
認証された 送信元メールアドレス
今回はSESをSandbox環境で使用するため送信元アドレスをSESに登録しておきます。まずはマネージメントのSESの画面を開きます。
画面左側の「Verified Senders - Email Addresses」をクリックしたら、「Verify a New Email Address」をクリックします。
登録するメールアドレスを入力し「Verify This Email Address」をクリックします。
入力したメールアドレス宛に認証確認メールが送信されます。
送られたメールを開き、中央のURLを開きます。(リンクをクリック)
メールアドレスが登録されました。
マネージメントコンソールに戻って画面を更新すると、メールアドレスが「verified」になっていることが確認できます。これでこのメールアドレスからメールを送ることができます。
後述しますがEC2からメールを送る際にはsendmailコマンドのコマンドラインで、このメールアドレスを指定することになります。
認証された 送信先メールアドレス
Sandbox環境では送信先メールアドレスも事前に登録が必要です。先ほどの送信元メールアドレス登録と同じ手順でメールアドレスを登録してください。今回はテストのため送信元と送信先のアドレスは同じものを使用しています。
設定作業
OpscodeのPublic CookbooksからPostfixのCookbookが利用できます。つまり自分でCookbookを作る必要はありません。各環境に合わせたAttributeを設定するためのJSONファイルをたった1つ用意するだけです。しかも変更するのはアクセスキーとシークレットキーのみ。簡単です。
$ cd ~/work/ $ knife solo init . $ vi Berksfile $ vi roles/postfix_ses_server.json $ berks install $ knife solo prepare -i keypair.pem [email protected] $ knife solo cook -i keypair.pem [email protected] -o "role[postfix_ses_server]"
Berksfile
site :opscode cookbook "postfix"
roles/postfix_ses_server.json
{ "name": "postfix_ses_server", "default_attributes": { "postfix" : { "main" : { "smtp_sasl_password_maps" : "hash:/etc/postfix/sasl_passwd", "relayhost" : "email-smtp.us-east-1.amazonaws.com:25", "smtp_sasl_auth_enable" : "yes", "smtp_use_tls" : "yes", "smtp_tls_security_level" : "encrypt", "smtp_tls_note_starttls_offer" : "yes", "smtp_tls_CAfile" : "/etc/ssl/certs/ca-bundle.crt" }, "sasl" : { "smtp_sasl_user_name" : "<your_access_key>", "smtp_sasl_passwd" : "<your_secret_key>" } } }, "json_class": "Chef::Role", "description": "This is a Role for setting up a postfix server", "chef_type": "role", "run_list": [ "recipe[postfix::sasl_auth]" ] }
動作確認
EC2にsshでログインしてメールを送ってみましょう。-tオプションでメッセージヘッダーから宛先アドレスを指定します。-fオプションで送信元アドレスを指定します。
$ sendmail -tf [email protected] To: [email protected] Subject: Test from Postfix SES relay server TEST .
送信先アドレスのメールを受信してみましょう。
成功です!無事届いています。
メールのヘッダーを確認すると、Message-IDやReturn-PathはSESのものになっています。
今回はSandbox環境で事前に送信先アドレスを登録したので問題ありませんでしたが、送信エラーでバウンスメールが返ってきた時にはSESで受け付け、処理をしてくれます。詳しくは以下のブログを参照してください。
Amazon SESでSPFとDKIMを用いて高信頼なメールを送る | Developers.IO
mailコマンドでメール送信
mailxパッケージがインストールされていれば、sendmailコマンドでなくmailコマンドでメールを送ることができます。シェルスクリプトからメールを送りたい場合には便利です。
$ mail -r [email protected] \ -s "TEST from mail" \ [email protected] <<_EOM_ TEST _EOM_
Postfixを使うメリット
Postfixを使ってSESを利用するメリットはなんでしょう?
ひとつはsendmailやmailコマンドを使ってメールを送ることができる点です。またPHPのmail()関数は、デフォルトでローカルのメールサーバー経由でメール送信をするので、その点でもお手軽です。
これ以外に、メール送信に失敗した場合にはキューに保存され再送してくれる点も使い勝手がいいのではないでしょうか。
(Postfixを停止する) $ sudo service postfix status master (pid 28090) is running... $ sudo service postfix stop Shutting down postfix: [ OK ] (Postfixサービスが停止している状態でメールを送る) $ sendmail -tf [email protected] To: [email protected] Subject: Test from Postfix SES relay server TEST (must be queued) . (配信できなかったメールはキューに溜まっている) $ sudo mailq postqueue: warning: Mail system is down -- accessing queue directly -Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient------- 977ED41F22 258 Sat Nov 9 02:31:57 [email protected] [email protected] -- 0 Kbytes in 1 Request. (Postfixを起動するとキューに溜まったメールが送信される) $ sudo service postfix start Starting postfix: [ OK ] $ sudo mailq Mail queue is empty
まとめ
OpscodeのPublic Cookbooksを使うことで、とても簡単にSESを利用したメール送信設定ができました。複数のEC2からメールを送ろうとすると、個別にEIPが必要だったり、逆引き設定や必要だったりといろいろ面倒です。
いろいろ悩むよりもSESを使うのがベストプラクティスです。さらにSESの信頼性をあげるためにはSPFやDKIMの設定も忘れないようにしましょう。
<
p class="aligncenter">Amazon SESでSPFとDKIMを用いて高信頼なメールを送る | Developers.IO